import xmpp, time, sha
from threading import Thread

workers = {}

class JabberConnectionThread(Thread):
    def __init__(self, session, **kwargs):
        self.session = session
        super(JabberConnectionThread, self).__init__(name=session.uuid,
                **kwargs)
    
    def run(self):
        self.running = True

        while self.running:
            if self.session.online:
                self.session.cl.Process(1)
    
    def stop(self):
        self.running = False

        global workers
        del workers[self.getName()]
            
class JabberSession(object):
    def __init__(self, jid, password):
        self.connected = False
        self.jid = xmpp.protocol.JID(jid)
        self.password = password
        
        self.uuid = sha.new("%s%s" % (self.jid, self.password,)).hexdigest()
        
        self.cl = xmpp.Client(self.jid.getDomain(), debug=[])
        self.con = self.connect_user(self.jid.getNode(), password)
        self.cl.sendInitPresence()
        self.roster = self.cl.getRoster()

        connection_thread = JabberConnectionThread(self) 
        connection_thread.start()
        global workers
        workers[connection_thread.getName()] = connection_thread
    
    def connect_user(self, jid, password):
        con = self.cl.connect()
        if not con:
            print('could not connect: %s\n' % (domain,))
            return False
            
        auth = self.cl.auth(self.jid.getNode(), password, resource=self.jid.getResource())

        if not auth:
#            print('could not authenticate: %s,%s,%s\n' % (self.jide.getNode(), self.jid.getResource(), password,))
            return False

        self.online = True
        return con
    
    def send(self, to_jid, message):
        if self.cl.send(xmpp.protocol.Message(to_jid, message)):
            return True
        else:
            return False

    def get_roster(self):
        if not self.roster:
            self.roster = self.cl.getRoster()
        return self.roster
    
    def refresh_roster(self):
        self.roster = self.cl.getRoster()

    def disconnect(self):
        self.online = False
        self.connected = False

    def authorize(self, jid):
        if not self.roster:
            self.get_roster()
        self.roster.authorize(jid)

    def unauthorize(self, jid):
        if not self.roster:
            self.get_roster()
        self.roster.unauthorize(jid)

    def subscribe(self, jid):
        if not self.roster:
            self.get_roster()
        self.roster.Subscribe(jid)

    def unsubscribe(self, jid):
        if not self.roster:
            self.get_roster()
        self.roster.Unsubscribe(jid)

    def remove(self, jid):
        if not self.roster:
            self.get_roster()
        self.roster.delItem(jid)
